/**
 * Copyright © 2018 organization baomidou
 * <pre>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * <pre/>
 */
package org.luxor.commons.jdbc.plugin.dynamic.properties;

import org.luxor.commons.core.utils.encrypt.AesEncryptUtils;
import org.luxor.commons.core.utils.encrypt.PbeEncryptUtils;
import org.luxor.commons.jdbc.plugin.dynamic.properties.hikari.HikariCpConfig;
import org.luxor.commons.jdbc.plugin.dynamic.strategy.DynamicDataSourceStrategy;
import org.luxor.commons.jdbc.plugin.dynamic.strategy.LoadBalanceDynamicDataSourceStrategy;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.core.Ordered;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * DynamicDataSourceProperties
 *
 * @author TaoYu Kanyuxia
 * @see DataSourceProperties
 * @since 1.0.0
 */
@ConfigurationProperties(prefix = DynamicDataSourceProperties.PREFIX)
public class DynamicDataSourceProperties {

    public static final String PREFIX = "spring.jdbc";

    /**
     * 启动动态数据源
     */
    private Boolean enabled = true;

    /**
     * 找不到数据源时，true-抛出异常；false-使用默认源
     */
    private Boolean strict = false;

    /**
     * 默认主库(必选)
     */
    private String primary = "master";

    /**
     * 是否使用p6spy输出，默认不输出
     */
    private Boolean p6spy = false;

    /**
     * 是否使用开启seata(AT模式)，默认不开启
     */
    private Boolean seata = false;

    /**
     * 每一个数据源的配置
     */
    private Map<String, DataSourceProperty> datasources = new LinkedHashMap<>();
    /**
     * 多数据源选择算法clazz，默认负载均衡算法
     */
    private Class<? extends DynamicDataSourceStrategy> strategy = LoadBalanceDynamicDataSourceStrategy.class;
    /**
     * aop切面顺序，默认优先级最高
     */
    private Integer order = Ordered.HIGHEST_PRECEDENCE;

    /**
     * HikariCp全局参数配置
     */
    @NestedConfigurationProperty
    private HikariCpConfig hikari;

    /**
     * 全局默认publicKey
     */
    private String publicKey = PbeEncryptUtils.DEFAULT_PUBLIC_KEY_STRING;

    /**
     * 全局默认数据加密秘钥
     */
    private String encryptSecret = AesEncryptUtils.AES_DATA_SECURITY_KEY;

    public DynamicDataSourceProperties() {
        HikariCpConfig global = new HikariCpConfig();
        // 连接池名称
        global.setPoolName("HikariPool-jdbc");
        // 自动提交从池中返回的连接
        global.setAutoCommit(true);
        // 数据库连接超时时间,默认30秒，即30000
        global.setConnectionTimeout(30000L);
        // 控制池中的连接的最长存活时间，值0表示无限，默认1800000即30分钟
        global.setMaxLifetime(1800000L);
        // 空闲连接最长存活时间，默认600000（10分钟）
        global.setIdleTimeout(600000L);
        // 最小空闲连接数
        global.setMinIdle(3);
        // 连接池中的最大连接数（包括空闲的和使用中的）
        global.setMaxPoolSize(35);
        // 如果连接池无法初始化数据库连接，将快速中断
        global.setInitializationFailTimeout(1L);
        // 测试连接操作的最长等待时间
        global.setValidationTimeout(5000L);
        // 把持连接30分钟不释放，代表存在连接泄漏问题
        global.setLeakDetectionThreshold(1800000L);
        this.hikari = global;
    }

    public String getPrimary() {
        return primary;
    }

    public void setPrimary(String primary) {
        this.primary = primary;
    }

    public Boolean getP6spy() {
        return p6spy;
    }

    public void setP6spy(Boolean p6spy) {
        this.p6spy = p6spy;
    }

    public Boolean getSeata() {
        return seata;
    }

    public void setSeata(Boolean seata) {
        this.seata = seata;
    }

    public Class<? extends DynamicDataSourceStrategy> getStrategy() {
        return strategy;
    }

    public void setStrategy(Class<? extends DynamicDataSourceStrategy> strategy) {
        this.strategy = strategy;
    }

    public Integer getOrder() {
        return order;
    }

    public void setOrder(Integer order) {
        this.order = order;
    }

    public HikariCpConfig getHikari() {
        return hikari;
    }

    public void setHikari(HikariCpConfig hikari) {
        this.hikari = hikari;
    }

    public String getPublicKey() {
        return publicKey;
    }

    public void setPublicKey(String publicKey) {
        this.publicKey = publicKey;
    }

    public String getEncryptSecret() {
        return encryptSecret;
    }

    public void setEncryptSecret(String encryptSecret) {
        this.encryptSecret = encryptSecret;
    }

    public Map<String, DataSourceProperty> getDatasources() {
        return datasources;
    }

    public void setDatasources(Map<String, DataSourceProperty> datasources) {
        this.datasources = datasources;
    }

    public Boolean getEnabled() {
        return enabled;
    }

    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    public Boolean getStrict() {
        return strict;
    }

    public void setStrict(Boolean strict) {
        this.strict = strict;
    }
}
